package co.edu.udea.iw.rtf.bl.impl;

import java.util.Date;
import java.util.List;

import co.edu.udea.iw.rtf.bl.SolicitudBL;
import co.edu.udea.iw.rtf.dao.ProductoDAO;
import co.edu.udea.iw.rtf.dao.SolicitudDAO;
import co.edu.udea.iw.rtf.dao.SucursalDAO;
import co.edu.udea.iw.rtf.dao.TipoSolicitudDAO;
import co.edu.udea.iw.rtf.dao.UsuarioDAO;
import co.edu.udea.iw.rtf.dto.Producto;
import co.edu.udea.iw.rtf.dto.Solicitud;
import co.edu.udea.iw.rtf.dto.Sucursal;
import co.edu.udea.iw.rtf.dto.TipoSolicitud;
import co.edu.udea.iw.rtf.dto.Usuario;
import co.edu.udea.iw.rtf.exception.RTFBlException;
import co.edu.udea.iw.rtf.exception.RTFDaoException;
import co.edu.udea.iw.rtf.util.EnviarEmail;

/**
 * Clase con la implementación en spring de la interfaz ProductoBL
 * @author Tatiana Escobar - tatescoal@gmail.com
 * @author Juan Camilo Cuartas - juancamilo.cuartas@gmail.com
 */
public class SolicitudBLImpl implements SolicitudBL {

	/**
	 * Objeto manejador de los metodos de solicitudDAO para SolicitudBLImpl
	 */
	SolicitudDAO solicitudDAO;
	
	/**
	 * Objeto manejador de los metodos de sucursalDAO para SolicitudBLImpl
	 */
	SucursalDAO sucursalDAO;
	
	/**
	 * Objeto manejador de los metodos de profuctoDAO para SolicitudBLImpl
	 */
	ProductoDAO productoDAO;
	
	/**
	 * Objeto manejador de los metodos de tipoSolicitudDAO para SolicitudBLImpl
	 */
	TipoSolicitudDAO tipoSolicitudDAO;
	
	/**
	 * Objeto manejador de los metodos de usuarioDAO para SolicitudBLImpl
	 */
	UsuarioDAO usuarioDAO;
	
	/**
	 * @see SolicitudBL#crearSolicitud(String, String, String, String, String, Sucursal, Producto, String, TipoSolicitud, String)
	 */
	@Override
	public Solicitud crearSolicitud(String nombreSolicitante, String apellidosSolicitante, String correoElectronico,
			String telefono, String celular, Sucursal sucursal, Producto producto, String cualOtroProducto,
			TipoSolicitud tipoSolicitud, String textoSolicitud) throws RTFDaoException, RTFBlException {
		try{
			if(nombreSolicitante == null || "".equals(nombreSolicitante))
				throw new RTFBlException("La nombre del solicitante no puede ser un valor nulo no vacio");
			
			if(apellidosSolicitante == null || "".equals(apellidosSolicitante))
				throw new RTFBlException("El apellido del solicitante no puede ser nulo ni un valor vacío");

			if(correoElectronico == null || "".equals(correoElectronico))
				throw new RTFBlException("El correo electronico del solicitante no puede ser nulo ni un valor vacío");
			
			if(telefono == null || "".equals(telefono))
				throw new RTFBlException("El telefono del solicitante no puede ser nulo ni un valor vacío");
			
			if(celular == null || "".equals(celular))
				throw new RTFBlException("El celular del solicitante no puede ser nulo ni un valor vacío");
			
			if(cualOtroProducto == null || "".equals(cualOtroProducto))
				throw new RTFBlException("El otro producto del solicitante no puede ser nulo ni un valor vacío");
			
			if(textoSolicitud == null || "".equals(textoSolicitud))
				throw new RTFBlException("El texto de la solicitud que va a realizar el solicitante no puede ser nulo ni un valor vacío");
			
			if(sucursal == null || "".equals(sucursal))
				throw new RTFBlException("El texto de la sucursal que va a realizar el solicitante no puede ser nulo ni un valor vacío");
		
			Sucursal objSucursal = sucursalDAO.obtener(sucursal.getCodigo());
			
			if(objSucursal == null)
				throw new RTFBlException("La sucursal ingresada debe ser una sucursal valida en el sistema");
			
			if(producto == null || "".equals(producto))
				throw new RTFBlException("El texto del producto que va a realizar el solicitante no puede ser nulo ni un valor vacío");
			
			Producto objProducto = productoDAO.obtener(producto.getCodigo());
			
			if(objProducto == null)
				throw new RTFBlException("El producto ingresado debe ser un producto valida en el sistema");
			
			if(tipoSolicitud == null || "".equals(tipoSolicitud))
				throw new RTFBlException("El texto dl tipo de solicitud que va a realizar el solicitante no puede ser nulo ni un valor vacío");
			
			TipoSolicitud objTipoSolicitud = tipoSolicitudDAO.obtener(tipoSolicitud.getCodigo());
			
			if(objTipoSolicitud == null)
				throw new RTFBlException("E tipo de solicitud ingresado debe ser valido en el sistema");
			
			
			Solicitud solicitud= new Solicitud();
			//solicitud.setCodigo(null);
			solicitud.setNombreSolicitante(nombreSolicitante);
			solicitud.setApellidoSolicitante(apellidosSolicitante);
			solicitud.setCorreoElectronico(correoElectronico);
			solicitud.setTelefono(telefono);
			solicitud.setCelular(celular);
			solicitud.setSucursal(objSucursal);
			solicitud.setProducto(objProducto);
			solicitud.setTipoSolicitud(objTipoSolicitud);
			solicitud.setTextoSolicitud(textoSolicitud);
			solicitud.setAsignada(false);
			solicitud.setRespondida(false);
			
			
			solicitudDAO.guardar(solicitud);
					
			return solicitud;
		}catch (Exception e) {
			throw new RTFBlException(e);			
		}
		
	}

	/**
	 * @see SolicitudBL#asignar(Usuario, Solicitud)
	 */
	@Override
	public void asignar(Usuario usuario, Solicitud solicitud) throws RTFDaoException, RTFBlException {
		// TODO Auto-generated method stub
		
		try{
			
			if(usuario == null || "".equals(usuario))
				throw new RTFBlException("El texto del usuario no puede ser nulo ni un valor vacío");
			
			if(solicitud == null || "".equals(solicitud))
				throw new RTFBlException("El texto de la solicitud  no puede ser nulo ni un valor vacío");
			
			Usuario objUsuario = usuarioDAO.obtener(usuario.getLogin());
			
			if(objUsuario == null)
				throw new RTFBlException("El usuario debe ser valido en el sistema");
			
			Solicitud objSolicitud = solicitudDAO.obtener(solicitud.getCodigo());
			
			if(objSolicitud == null)
				throw new RTFBlException("La solicitud debe ser valida en el sistema");
			
			objSolicitud.setUsuarioAsignada(usuario);
			objSolicitud.setFechaAsignacion(new Date());
			
			solicitudDAO.actualizar(objSolicitud);
		}catch (Exception e) {
			throw new RTFBlException(e);			
		}
	}

	/**
	 * @see SolicitudBL#responder(Solicitud, Usuario, String)
	 */
	@Override
	public void responder(Solicitud solicitud, Usuario usuarioResponde, String respuesta) throws RTFDaoException, RTFBlException {
		
		try{
			
			if(solicitud == null || "".equals(solicitud))
				throw new RTFBlException("El texto de la solicitud no puede ser nulo ni un valor vacío");
			
			if(usuarioResponde == null || "".equals(usuarioResponde))
				throw new RTFBlException("El texto del usuario no puede ser nulo ni un valor vacío");		
			
			Usuario objUsuario = usuarioDAO.obtener(usuarioResponde.getLogin());
			
			if(objUsuario == null)
				throw new RTFBlException("El usuario debe ser valido en el sistema");
		
			Solicitud objSolicitud = solicitudDAO.obtener(solicitud.getCodigo());
			
			if(objSolicitud == null)
				throw new RTFBlException("La solicitud debe ser valida en el sistema");
			
			if(respuesta == null || "".equals(respuesta))
				throw new RTFBlException("La respuesta al solicitante no puede ser nulo ni un valor vacío");
			
			objSolicitud.setUsuarioResponde(usuarioResponde);
			objSolicitud.setTextoRespuesta(respuesta);
			objSolicitud.setFechaRespuesta(new Date());

			solicitudDAO.actualizar(objSolicitud);
			
			notificarCliente(objSolicitud, "Respuesta Solicitud Numero: "+solicitud.getCodigo(), respuesta);
			
			
		}catch (Exception e) {
			throw new RTFBlException(e);			
		}
		
	}
	
	
	/**
	 * @see SolicitudBL#obtener(Integer)
	 */
	@Override
	public Solicitud obtener(Integer codigo) throws RTFDaoException, RTFBlException {
		// TODO Auto-generated method stub
		
		try{
			Solicitud solicitudObtenida = null;
			
			if(codigo == null || "".equals(codigo)){
				throw new RTFBlException("El codigo de la solicitud no puede ser un valor nulo o vacio");
			}
				
			solicitudObtenida = solicitudDAO.obtener(codigo);
			
			if(solicitudObtenida == null || "".equals(solicitudObtenida)){
				throw new RTFBlException("El codigo no pertenece a una solicitud del sistema");
			}
			
			return solicitudObtenida;
			
		}catch (Exception e) {
			throw new RTFBlException(e);			
		}
	}

	/**
	 * @see SolicitudBL#obtenerAsignadas(String)
	 */
	@Override
	public List<Solicitud> obtenerAsignadas(String usuario) throws RTFDaoException, RTFBlException {
		// TODO Auto-generated method stub
		try{
			List<Solicitud> solicitudes;
			
			if(usuario == null || "".equals(usuario)){
				throw new RTFBlException("El usuario asignado no puede ser un valor nulo o vacio");
			}
				
			solicitudes = solicitudDAO.obtenerAsignadas(usuario);
			
			return solicitudes;
			
		}catch (Exception e) {
			throw new RTFBlException(e);			
		}
	}

	/**
	 * @see SolicitudBL#obtenerSinResponder(String)
	 */
	@Override
	public List<Solicitud> obtenerSinResponder(String usuario) throws RTFDaoException, RTFBlException {
		// TODO Auto-generated method stub
		try{
			List<Solicitud> solicitudes;
			
			if(usuario == null|| "".equals(usuario)){
				throw new RTFBlException("El usuario asignado no puede ser un valor nulo o vacio");
			}
				
			solicitudes = solicitudDAO.obtenerSinResponder(usuario);
			
			return solicitudes;
			
		}catch (Exception e) {
			throw new RTFBlException(e);			
		}
	}

	/**
	 * @see SolicitudBL#obtenerPendientesPorSucursal(Integer)
	 */
	@Override
	public List<Solicitud> obtenerPendientesPorSucursal(Integer sucursal) throws RTFDaoException, RTFBlException {
		try{
			
			if(sucursal == null|| "".equals(sucursal)){
				throw new RTFBlException("El texto se la sucursal ingresada no puede ser un valor nulo o vacio");
			}
			
			List<Solicitud> solicitudes;
			
			Sucursal objSucursal = sucursalDAO.obtener(sucursal);
			
			if(objSucursal == null)
				throw new RTFBlException("La sucursal ingresada debe ser valida en el sistema");
				
			solicitudes = solicitudDAO.obtenerPendientePorSucursal(objSucursal);
			
			if(solicitudes == null|| "".equals(solicitudes)){
				throw new RTFBlException("No existe una solicitud con esa sucursal en el sistema");
			}
			
			return solicitudes;
			
		}catch (Exception e) {
			throw new RTFBlException(e);			
		}
	}

	/**
	 * @see SolicitudBL#obtenerPorSucursal(Integer)
	 */
	@Override
	public List<Solicitud> obtenerPorSucursal(Integer sucursal) throws RTFDaoException, RTFBlException {

		try{
			
			if(sucursal == null|| "".equals(sucursal)){
				throw new RTFBlException("El texto de la sucursal no puede ser un valor nulo o vacio");
			}
			
			List<Solicitud> solicitudes;
			
			Sucursal objSucursal = sucursalDAO.obtener(sucursal);
			
			if(objSucursal == null)
				throw new RTFBlException("La sucursal ingresada debe ser valida en el sistema");
				
			solicitudes = solicitudDAO.obtenerPorSucursal(objSucursal);
			
			if(solicitudes == null|| "".equals(solicitudes)){
				throw new RTFBlException("No existe una solicitud con esa sucursal en el sistema");
			}
			
			return solicitudes;
			
		}catch (Exception e) {
			throw new RTFBlException(e);			
		}
	}

	/**
	 * @see SolicitudBL#obtener()
	 */
	@Override
	public List<Solicitud> obtener() throws RTFDaoException, RTFBlException {
		
		try{
			List<Solicitud> solicitudes;

			solicitudes = solicitudDAO.obtener();
			
			return solicitudes;
		}catch (Exception e) {
			throw new RTFBlException(e);			
		}
	}

	public SolicitudDAO getSolicitudDAO() {
		return solicitudDAO;
	}

	public void setSolicitudDAO(SolicitudDAO solicitudDAO) {
		this.solicitudDAO = solicitudDAO;
	}
	
	public SucursalDAO getSucursalDAO() {
		return sucursalDAO;
	}

	public void setSucursalDAO(SucursalDAO sucursalDAO) {
		this.sucursalDAO = sucursalDAO;
	}

	public ProductoDAO getProductoDAO() {
		return productoDAO;
	}

	public void setProductoDAO(ProductoDAO productoDAO) {
		this.productoDAO = productoDAO;
	}

	public TipoSolicitudDAO getTipoSolicitudDAO() {
		return tipoSolicitudDAO;
	}

	public void setTipoSolicitudDAO(TipoSolicitudDAO tipoSolicitudDAO) {
		this.tipoSolicitudDAO = tipoSolicitudDAO;
	}

	public UsuarioDAO getUsuarioDAO() {
		return usuarioDAO;
	}

	public void setUsuarioDAO(UsuarioDAO usuarioDAO) {
		this.usuarioDAO = usuarioDAO;
	}

	/**
	 * metodo usado en el metodo responder que envia un correo electronico
	 * @param solicitud es la solicitud que contiene el correo del cliente al que se envia el mensaje
	 * @param asunto del correo electronico que se envía al cliente
	 * @param mensaje del correo electronico que se envía al cliente
	 */
	@Override
	public void notificarCliente(Solicitud solicitud, String asunto, String mensaje) throws RTFDaoException, RTFBlException {
	
		EnviarEmail email = new EnviarEmail();
		
		try {
			email.sendEmail(solicitud.getCorreoElectronico(), asunto, mensaje);
		} catch (RTFBlException e) {
			e.printStackTrace();
		}
	}

	@Override
	public List<Solicitud> obtenerSinAsignar() throws RTFDaoException,
			RTFBlException {
		// TODO Auto-generated method stub
		try{
			List<Solicitud> solicitudes;

			solicitudes = solicitudDAO.obtenerSinAsignar();
			
			return solicitudes;
		}catch (Exception e) {
			throw new RTFBlException(e);			
		}
	}

}
